package room_event

import (
	"encoding/json"
	"fmt"
	"html"
	"log"
	"longmen/server/config/global"
	"longmen/server/internal/rpc/tencentim/api"
	"longmen/server/internal/rpc/tencentim/chat"
	messages2 "longmen/server/internal/rpc/tencentim/messages"
	"longmen/server/internal/rpc/tencentim/utils"
	"longmen/server/pkg/common/helper/blackWorlds"
	"longmen/server/pkg/db/mysql/models/models_live"
	"longmen/server/pkg/db/mysql/models/models_main"
	pb "longmen/server/pkg/protobuf"
	"time"

	"github.com/spf113/cast"

	"github.com/go-redis/redis"
)

func userCanSay(usr *chat.ClientUser) (bool, error) {
	// 检查是否在禁言列表中
	/*list, err := api.GetAPI().GetBannedUserList(usr.RoomId, usr)
	if err != nil {
		return false, err
	} else {
		for _, item := range list.UserList {
			if int(item.Id) == usr.SenderUid {
				return false, fmt.Errorf("用户在禁言列表中")
			}
		}
	}
	*/
	// 检查发言频率
	rdc := global.GetRds()
	key := fmt.Sprintf("%s%d", "roomSayNumUid_", usr.UserId)
	sayCount, err := rdc.Get(key).Int()
	if err == redis.Nil {
		// 如果发言计数器不存在，则视为可以发言
		return true, nil
	}
	if err != nil {
		// 如果读取计数器失败，则假定可以发言
		global.Log.Errorf("ROOM[%d]: get user say count failed, %s", usr.RoomId, err)
		return true, nil
	}

	if sayCount < 4 {
		return true, nil
	}

	// 达到短时间内的最大发言次数
	if sayCount == 5 {
		// 更新计数器，并设定缓存有效期
		_ = rdc.Set(key, sayCount+1, 5000*time.Millisecond).Err()
	}

	return false, fmt.Errorf("room[%d] uid[%d]【发言过于频繁，请稍后再试】", usr.RoomId, usr.UserId)
}

func handlingSayMessage(user *chat.ClientUser, b []byte) (result *pb.CallbackResp) {
	// 默认返回值
	result = &pb.CallbackResp{}
	rep := &messages2.ReplyMessage{Type: messages2.ErrorReplyMessageType}

	// 解析消息内容
	m := messages2.SayMessage{}
	if err := json.Unmarshal(b, &m); err != nil {
		rep.Code = 1
		rep.Message = fmt.Sprintf("invalid message struct, %s", err)
		return utils.CallbackFailResp(rep, rep.Message)
	}

	// 验证内容是否为空
	if len(m.Content) == 0 {
		rep.Code = 1
		rep.Message = "内容不能为空"
		return utils.CallbackFailResp(rep, rep.Message)
	}

	// 检查用户是否可以发送消息
	if ok, err := userCanSay(user); !ok {
		global.Log.Errorf("err:%v", err)
		rep.Code = 1
		rep.Message = err.Error()
		return utils.CallbackFailResp(rep, rep.Message)
	}

	// 获取聊天 ID
	chatId := api.GetAPI().GetChatMaxId()

	// 格式化内容，避免 HTML 注入
	content := html.EscapeString(cast.ToString(m.Content))
	if len(content) > 60 {
		content = content[:60] // 限制最大长度为 60
	}

	// 黑词过滤
	filteredContent := blackWorlds.BlackWorInstance.ReplaceWithAsterisk(content)

	// 构建发送消息对象
	resp := &messages2.RoomUserSayMessageToNats{
		SentMessageStruct: messages2.SentMessageStruct{Type: messages2.RoomUserSayMessageType},
		Id:                chatId,
		Content:           filteredContent,
		UserId:            user.UserId,
		ClientName:        user.ClientName,
		Level:             user.Level,
		Props:             user.Props,
		RoomId:            user.RoomId,
		Role:              user.Role,
		CreateTime:        time.Now().Unix(),
	}

	global.Log.Debugf("构建发送消息对象:%+v\n", resp)

	// 返回成功响应
	return utils.CallbackOkResp(resp)
}

func SayAfter(user *chat.ClientUser, roomId int, req *pb.CallbackReq, text string, richData string) (result *pb.CallbackResp) {
	rep := &messages2.ReplyMessage{
		Type:    messages2.SayReplyMessageType,
		Message: "success",
	}
	cloudData := messages2.SayMessageAfterCloudData{}
	_ = json.Unmarshal([]byte(req.CloudCustomData), &cloudData)
	global.Log.Infof("sayafter[%d]: %s", roomId, req.CloudCustomData)
	GetChatHistory(roomId).AppendChatHistory(messages2.ChatHistory{
		Id:         req.MsgSeq,
		Activity:   int32(cloudData.Activity),
		Content:    text,
		UserId:     int64(user.UserId),
		ClientName: user.ClientName,
		Level:      user.Level,
		Vip:        user.Vip,
		Role:       user.Role,
		Type:       messages2.RoomUserSayMessageType,
		Rich:       richData,
		FontColor:  "", //cloudData.FontColor,
	})

	// 活动发言统计
	if cloudData.Activity == 1 {
		var abid int
		err := global.GetR().Model(&models_main.ActivityBarrage{}).Where("status=1").Pluck("id", &abid).Error
		if err != nil {
			global.Log.Infof("Activity Stat Error: %s", err.Error())
		}
		var liveID int64
		err = global.Live().Model(&models_live.Live{}).Where("anchorid=?", roomId/100).Pluck("liveid", &liveID).Error
		if err != nil {
			global.Log.Infof("Activity Stat Error: %s", err.Error())
		}
		key := fmt.Sprintf("ACTIVITY_STAT_%d_%d_%d", roomId, abid, liveID)
		field := fmt.Sprintf("%d", user.UserId)
		err = global.GetRds().HSet(key, field, 1).Err()
		log.Println("say-message=====>key:", key, "field:", field, "err:", err)
		rets, _ := global.GetRds().HGetAll(key).Result()
		cloudData.ActivitySum = len(rets)
	}

	return utils.CallbackOkResp(rep)
}
